import OriginBraftEditor, { BraftEditorProps, EditorState } from 'braft-editor'
import 'braft-editor/dist/index.css'
import { getTenantToken, getPlatformToken } from '@designable/event-system'
import React, { useState, useEffect, useCallback } from 'react'

type Mixins = {
  channel: string
}

const validateResponseState = (res: { code: number; msg: string; data: any }) =>
  res.code === 0 ? Promise.resolve(res.data.fileUrl) : Promise.reject(res.msg)

const defaultProps: Partial<BraftEditorProps & Mixins> = {
  media: {
    accepts: {
      image: 'image/png,image/jpeg',
      video: 'video/mp4',
      audio: false,
    },
    externals: {
      image: true,
      audio: false,
      video: false,
      embed: false,
    },
    uploadFn(param) {
      const tenantToken = getTenantToken()
      const data = new FormData()
      data.append('image', param.file)
      const onerror = () => void param.error({ msg: '上传失败' })
      const xhr = new XMLHttpRequest()
      xhr.open(
        'post',
        `${
          tenantToken
            ? '/api/tenant/upload/image'
            : '/api/platform/upload/image'
        }`,
        true
      )
      xhr.setRequestHeader('platform-token', getPlatformToken() || '')
      xhr.setRequestHeader('tenant-token', getTenantToken() || '')
      xhr.onerror = onerror
      xhr.onabort = onerror
      xhr.onprogress = (e) => param.progress((e.loaded / e.total) * 100)
      xhr.onload = () =>
        Promise.resolve(xhr.responseText)
          .then(JSON.parse)
          .then(validateResponseState)
          .then((url: string) =>
            param.success({
              url,
              meta: {
                id: param.libraryId,
                title: param.file.name,
                alt: '图片',
                loop: false,
                autoPlay: false,
                controls: true,
                poster: '',
              },
            })
          )
          .catch(onerror)
      xhr.send(data)
    },
  },
  language: 'zh',
}

interface EditorProps {
  value?: string
  onChange?: (value: string) => void
  disabled?: boolean
}

const isContentEmpty = (content: EditorState) => {
  return content.toHTML() === '<p></p>'
}

export function BraftEditor(props: EditorProps) {
  const { onChange, value, disabled } = props
  const [content, setContent] = useState<EditorState>(
    OriginBraftEditor.createEditorState(value || '')
  )
  useEffect(() => {
    // 如果 value 有值且 content 没有值，就重新设置一遍默认值
    if (value && (isContentEmpty(content) || value !== content.toHTML())) {
      setContent(OriginBraftEditor.createEditorState(value))
    }
  }, [content, value])

  const handleChange = useCallback(
    (value: EditorState) => {
      if (onChange) {
        let html = value.toHTML()
        if (html === '<p></p>') {
          html = ''
        }
        onChange(html)
      }
      setContent(value)
    },
    [onChange]
  )

  const BEprops = {
    ...props,
    ...defaultProps,
    media: {
      ...defaultProps.media,
    },
    value: content,
    onChange: handleChange,
  }

  return (
    <div
      className={'ant-input'}
      style={{ cursor: disabled ? 'not-allowed' : 'auto' }}
    >
      <OriginBraftEditor
        {...BEprops}
        contentStyle={{
          height: '150px',
        }}
      />
    </div>
  )
}
